// This file is part of the RECODER library and protected by the LGPL.

package recodercs.csharp.statement;


import recodercs.*;
import recodercs.abstraction.*;
import recodercs.csharp.*;
import recodercs.csharp.declaration.*;
import recodercs.list.*;
import recodercs.util.Debug;

/**
 For.
 @author <TT>AutoDoc</TT>
 */

public class For extends LoopStatement implements VariableScope {

    /**
     For.
     */

    public For() {}

    /**
     For.
     @param inits a loop initializer mutable list.
     @param guard an expression.
     @param updates an expression mutable list.
     @param body a statement.
     */

    public For(LoopInitializerMutableList inits, Expression guard,
               ExpressionMutableList updates, Statement body) {
        super(body);
        setInitializers(inits);
        setGuard(guard);
        setUpdates(updates);
        makeParentRoleValid();
    }

    /**
     For.
     @param proto a for.
     */

    protected For(For proto) {
        super(proto);
        makeParentRoleValid();
    }

    /**
     Deep clone.
     @return the object.
     */

    public Object deepClone() {
        return new For(this);
    }


    public SourceElement getLastElement() {
        return (body != null) ? body.getLastElement() : this;
    }

    /**
     Set initializers.
     @param list a loop initializer mutable list.
     */

    public void setInitializers(LoopInitializerMutableList list) {
        inits = list;
    }

    /**
     Set updates.
     @param list an expression mutable list.
     */

    public void setUpdates(ExpressionMutableList list) {
        updates = list;
    }

    /**
     Is exit condition.
     @return the boolean value.
     */

    public boolean isExitCondition() {
        return false;
    }

    /**
     Is checked before iteration.
     @return the boolean value.
     */

    public boolean isCheckedBeforeIteration() {
        return true;
    }

    public boolean isDefinedScope() {
        return true;
    }

    public void setDefinedScope(boolean defined) {}

    public VariableSpecificationList getVariablesInScope() {
        if (inits != null) {
            LoopInitializer li = inits.getLoopInitializer(0);
            if (li instanceof LocalVariableDeclaration) {
                return ((LocalVariableDeclaration)li).getVariables();
            }
        }
        return VariableSpecificationList.EMPTY_LIST;
    }

    public VariableSpecification getVariableInScope(String name) {
        Debug.asserta(name);
        if (inits != null) {
            LoopInitializer li = inits.getLoopInitializer(0);
            if (li instanceof LocalVariableDeclaration) {
                VariableSpecificationList vars =
                    ((LocalVariableDeclaration)li).getVariables();
                for (int i = 0, s = vars.size(); i < s; i += 1) {
                    VariableSpecification v = vars.getVariableSpecification(i);
                    if (name.equals(v.getName())) {
                        return v;
                    }
                }
            }
        }
        return null;
    }

    public void addVariableToScope(VariableSpecification var) {
        Debug.asserta(var);
    }

    public void removeVariableFromScope(String name) {
        Debug.asserta(name);
    }

    public void accept(SourceVisitor v) {
        v.visitFor(this);
    }
}
